package Autopeli;

/*
 * AutoPeli.java
 *
 * Created on 12. maaliskuuta 2005, 8:56
 */

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform; 
//import java.awt.geom.Area;
import javax.swing.JApplet;
import javax.swing.JPanel;

/**
 *
 * @author mapas
 */
public class AutoPeli extends JApplet implements Runnable, MouseListener {

    private Thread saie;
    private MediaTracker mt;
    private Image rata;
    // originaali koordinaatisto
    private AffineTransform origTrans;
    // auton siirto
    private AffineTransform autoTrans;
    // onko n�pp�in alhaalla
    private boolean left, right, up, down;
    // tarkistuspisteet
    private Checkpoint checkpoints[];
    private boolean checked[] = {false, false, false, false};
    // auto
    private Car car;
    private double bestLap;
    private double startLap;
    // fontti
    private Font f1;
    // game mode 1 == menu, 2 == game running
    private int gameMode; 

    @Override
    public void init() {
        mt = new MediaTracker(this);
        System.out.println(getDocumentBase());
        Image auto = getImage(getDocumentBase(), "auto2.gif");
        rata = getImage(getDocumentBase(), "rata.jpg");
        Image cp1 = getImage(getDocumentBase(), "checkpoint1.png");
        Image cp2 = getImage(getDocumentBase(), "checkpoint2.png");
        Image cp3 = getImage(getDocumentBase(), "checkpoint3.png");
        try {
            mt.addImage(auto, 0);
            mt.addImage(rata, 1);
            mt.addImage(cp1, 2);
            mt.addImage(cp2, 2);
            mt.addImage(cp3, 2);
            mt.waitForAll();
        } catch (InterruptedException e) {
        }
        // kiinnitet��n SWING-appletin piirto
        PiirtoPaneeli paneeli = new PiirtoPaneeli();
        getContentPane().add(paneeli);
        // alustetaan n�pp�imist�nkuuntelija sis�isell� luokalla
        KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
        manager.addKeyEventDispatcher(new MyDispatcher());
        // hiiren k�sittely
        addMouseListener(this);
        // oletuksena ei ole painettu nuolin�pp�imi�
        left = right = up = down = false;
        // m��ritell��n esteet
        checkpoints = new Checkpoint[4];
        checkpoints[0] = new Checkpoint(10, 285, cp3);
        checkpoints[1] = new Checkpoint(400, 8, cp2);
        checkpoints[2] = new Checkpoint(699, 285, cp1);
        checkpoints[3] = new Checkpoint(400, 500, cp2);
        // otetaan autolle k�ytt��n oma koordinaatisto
        autoTrans = new AffineTransform();
        origTrans = new AffineTransform();
        car = new Car(auto);
        f1 = new Font("Verdana",Font.BOLD,30);
        bestLap = Double.MAX_VALUE;
        startLap = 0;
        gameMode = 1;
    }

    @Override
    public void start() {
        if (saie == null) {
            saie = new Thread(this);
            saie.start();
        }
    }

    // run metodi, s�iett� suoritetaan niin kauan kuin run metodia
    @Override
    public void run() {
        while (true) {
            // k�sitell��n auton k��ntyminen
            if (left) {
                car.setAngle(-0.2);
            }
            if (right) {
                car.setAngle(0.2);
            }
            if (!left && !right) {
                car.resetAngle();
            }
            // k�sitell��n auton nopeus
            if (up) {
                car.setSpeed(1.0);
            }
            if (down) {
                car.setSpeed(-1.0);
            }
            if (!up && !down) {
                car.resetSpeed();
            }
            // collision
            checkCollision();

            // piirret��n n�ytt� uudelleen ja laitetaan s�ie nukkumaan
            repaint();
            try {
                saie.sleep(15);
            } catch (InterruptedException ie) {
            }
        }
    }

    public void isCheckpoint(Rectangle carNow) {
        int checkpoint = -1;
        // huom! t�ss� tutkitaan suorakulmion muotoisia alueita!!
        for (int i = 0; i < checkpoints.length; i++) {
            if (carNow.intersects(checkpoints[i].getX(), checkpoints[i].getY(), checkpoints[i].getW(), checkpoints[i].getH())) {
                checked[i] = true;
                checkpoint = i;
                break;
            }
        }
        // onko kaikki checkpointit kohdattu
        boolean all = true;
        for (int i = 0; i < checked.length; i++) {
            if (!checked[i]) {
                all = false;
                break;
            }
        }
        // onko kaikki checkpointit kohdattu ja ollaan "maalissa"
        if (all && checkpoint == 0) {
            System.out.println("LAP!");
            double time = System.currentTimeMillis() - startLap;
            if (time < bestLap) bestLap = time;
            for (int i = 0; i < checked.length; i++) {
                checked[i] = false;
            }
            startLap = System.currentTimeMillis();
        }
    }

    public void checkCollision() {
        // otetaan autosta shape
        Rectangle carRec = new Rectangle(car.getX(), car.getY(), car.getImage().getWidth(null), car.getImage().getHeight(null));
        // m��ritell��n auto shapen transform
        //autoTrans.createTransformedShape(carRec);
        // m��ritell��n auton shapesta alue
        //Area carArea = new Area(carRec);
        // m��ritell��n auton shapen rectangle
        //Rectangle carNow = autoTrans.createTransformedShape(carArea).getBounds();
        Rectangle carNow = autoTrans.createTransformedShape(carRec).getBounds();
        System.out.println("Auton tod x: "+carNow.getX()+" ja y: "+carNow.getY());
        // osuuko auto johonkin esteeseen
        isCheckpoint(carNow);

    }

    // SWING-applettiin piirt�v� luokka
    class PiirtoPaneeli extends JPanel {

        @Override
        public void paintComponent(Graphics g) {
            // taustan piirto ei tarvita 
            super.paintComponent(g);

            switch (gameMode) {
                case 1: drawMenu(g); break; 
                case 2: drawGame(g); break;
            }
        }
        
        public void drawMenu(Graphics g) {
            g.setColor(Color.BLACK);
            g.setFont(f1);
            g.drawString("Click Screen to start a game!",180,300);
        }
        
        
        public void drawGame(Graphics g) {
            // otetaan k�ytt��n Graphics 2D
            Graphics2D g2d = (Graphics2D) g;
            // piirret��n rata
            g2d.drawImage(rata, 0, 0, this);
            // piirr� checkpointit
            for (int i = 0; i < checkpoints.length; i++) {
                g2d.drawImage(checkpoints[i].getImage(), checkpoints[i].getX(), checkpoints[i].getY(), this);
            }
            // m��ritell��n auton keskipiste
            int xRot = car.getX() + car.getImage().getWidth(null) / 2;
            int yRot = car.getY() + car.getImage().getHeight(null) / 2;
            // m��ritell��n auton k��nt� auton keskipisteen suhteen
            autoTrans.rotate(Math.toRadians(car.getAngle()), xRot, yRot);
            // m��ritell��n k�ytt��n auton koordinaatisto
            g2d.setTransform(autoTrans);
            //piirret��n auto
            g2d.drawImage(car.getImage(), car.getX(), car.getY(), this);
            // lap
            g2d.setColor(Color.WHITE);
            g2d.setFont(f1);
            g2d.setTransform(origTrans);
            if (bestLap != Double.MAX_VALUE) 
                g2d.drawString("Best Lap : " +  bestLap,200,300);
            g2d.drawString("Lap : " + (System.currentTimeMillis() - startLap),200,350);
            g2d.drawString("xRot: "+xRot+" ,yRot: "+yRot,200,400);
        }
    }

    class MyDispatcher implements KeyEventDispatcher {

        @Override
        public boolean dispatchKeyEvent(KeyEvent e) {
            
            if (e.getID() == KeyEvent.KEY_PRESSED) {
                switch (e.getKeyCode()) {
                    case KeyEvent.VK_LEFT:
                        left = true;
                        break;
                    case KeyEvent.VK_RIGHT:
                        right = true;
                        break;
                    case KeyEvent.VK_UP:
                        up = true;
                        down = false;
                        break;
                    case KeyEvent.VK_DOWN:
                        down = true;
                        up = false;
                        break;
                }
            } else if (e.getID() == KeyEvent.KEY_RELEASED) {
                switch (e.getKeyCode()) {
                    case KeyEvent.VK_LEFT:
                        left = false;
                        break;
                    case KeyEvent.VK_RIGHT:
                        right = false;
                        break;
                    case KeyEvent.VK_UP:
                        up = false;
                        break;
                    case KeyEvent.VK_DOWN:
                        down = false;
                        break;
                }
            }
            // true if the KeyboardFocusManager should take no further action with regard to the KeyEvent; false otherwise
            return true;
        }
    }
    
    @Override
    public void mouseExited(MouseEvent e) {}
    @Override
    public void mouseEntered(MouseEvent e) {}
    @Override
    public void mouseClicked(MouseEvent e) {}
    @Override
    public void mouseReleased(MouseEvent e) {}
    @Override
    public void mousePressed(MouseEvent e) {
        if (gameMode == 1) {
            gameMode = 2; 
            startLap = System.currentTimeMillis();
        }
    }
    
}